package org.summerframework.component.upload.type;

import org.summerframework.component.upload.UploadResultCode;
import org.summerframework.core.base.dto.BaseDTO;
import org.summerframework.core.exception.WebException;
import org.summerframework.core.util.ConvertUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
public class FileUploadDTO extends BaseDTO {

    private static final long serialVersionUID = -3083640155126354085L;

    @ApiModelProperty(hidden = true)
    private String fileName;

    @ApiModelProperty(hidden = true)
    private String name;

    @ApiModelProperty(hidden = true)
    private String ext;

    @ApiModelProperty(hidden = true)
    private Long folderId = 0L;

    @ApiModelProperty(hidden = true)
    private InputStream inputStream;

    @ApiModelProperty(hidden = true)
    private byte[] fileBytes;

    @ApiModelProperty(hidden = true)
    private Long userId;

    @ApiModelProperty(notes = "压缩图片的宽")
    private Integer width = 500;

    @ApiModelProperty(notes = "压缩图片的高")
    private Integer height = 500;

    @ApiModelProperty(notes = "强制要求用户上传指定类型  1:图片 2:音乐 3:视频")
    private Integer type;

    @ApiModelProperty(notes = "是否需要压缩, 默认压缩")
    private Boolean needHandle = true;

    public static List<FileUploadDTO> request(MultipartHttpServletRequest request, FileUploadDTO fileUploadDTO) {
        List<FileUploadDTO> list = new ArrayList<>();
        if (request != null) {
            for (String key : request.getFileMap().keySet()) {
                final FileUploadDTO newFileUploadDTO = ConvertUtils.copyProperties(fileUploadDTO, FileUploadDTO.class);
                newFileUploadDTO.setFile(request.getFileMap().get(key));
                list.add(newFileUploadDTO);
            }
        }

        return list;
    }

    public static FileUploadDTO file(MultipartFile file) {
        try {
            FileUploadDTO fileUploadDTO = new FileUploadDTO();
            fileUploadDTO.setFileName(file.getOriginalFilename());
            fileUploadDTO.setInputStream(file.getInputStream());
            return fileUploadDTO;
        } catch (Exception e) {
            throw new WebException(UploadResultCode.ERROR_UPLOAD_FAILURE);
        }
    }

    public void setFile(MultipartFile file) {
        try {
            this.setFileName(file.getOriginalFilename());
            this.setInputStream(file.getInputStream());
        } catch (Exception e) {
            throw new WebException(UploadResultCode.ERROR_UPLOAD_FAILURE);
        }
    }

    public static FileUploadDTO file(byte[] bytes, String fileName) {
        FileUploadDTO fileUploadDTO = new FileUploadDTO();
        fileUploadDTO.setFileName(fileName);
        fileUploadDTO.setFileBytes(bytes);
        return fileUploadDTO;
    }

    public static FileUploadDTO file(InputStream inputStream, String fileName) {
        FileUploadDTO fileUploadDTO = new FileUploadDTO();
        fileUploadDTO.setFileName(fileName);
        fileUploadDTO.setInputStream(inputStream);
        return fileUploadDTO;
    }

    public static FileUploadDTO file(URL url) throws IOException {
        FileUploadDTO fileUploadDTO = new FileUploadDTO();
        fileUploadDTO.setFileName(FilenameUtils.getName(url.getPath()));
        fileUploadDTO.setFileBytes(IOUtils.toByteArray(url));
        return fileUploadDTO;
    }

    public static FileUploadDTO file(URL url, String fileName) throws IOException {
        FileUploadDTO fileUploadDTO = new FileUploadDTO();
        fileUploadDTO.setFileName(fileName);
        fileUploadDTO.setFileBytes(IOUtils.toByteArray(url));
        return fileUploadDTO;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
        this.name = FilenameUtils.getBaseName(fileName);
        this.ext = FilenameUtils.getExtension(fileName);
    }
}
